package com.lovo.config;

import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

@Configuration
public class QueueConfig {
    //注入工厂（已经预加载）
    @Autowired
    CachingConnectionFactory connectionFactory;
    //注入用户
    @Autowired
    RabbitAdmin rabbitAdmin;

    //rabbitmq模板
    @Bean(value = "rabbitTemplate")
    public RabbitTemplate rabbitTemplate() {
        return new RabbitTemplate(connectionFactory);
    }

    @Bean(value = "rabbitAdmin")
    public RabbitAdmin rabbitAdmin() {
        return new RabbitAdmin(connectionFactory);
    }

    /**
     * 创建死信交换机
     *
     * @return
     */
    @Bean
    public DirectExchange directDeadExchange() {
        return new DirectExchange("directDeadExchange");
    }

    /**
     * 创建普通交换机
     *
     * @return
     */
    @Bean
    public DirectExchange directExchange() {
        return new DirectExchange("orderEx");
    }

    /**
     * 创建普通队列
     * 将死信交换机关联至普通队列，
     * 普通队列的信息失效后将会传入死信交换机
     *
     * @return
     */
    @Bean
    public Queue queueOrder() {
        //关联死信交换机
        Map<String, Object> args = new HashMap<>(3);
        // x-dead-letter-exchange    这里声明当前队列绑定的死信交换机
        args.put("x-dead-letter-exchange", "directDeadExchange");
        // x-dead-letter-routing-key  这里声明当前队列的死信路由key
        args.put("x-dead-letter-routing-key", "deadKEY");
        // x-message-ttl  声明队列的TTL
        args.put("x-message-ttl", 5000);
        return QueueBuilder.durable("queueOrder").withArguments(args).build();
    }

    /**
     * 创建死信队列
     */
    @Bean
    public Queue queueDead() {
        return new Queue("queueDead");
    }

    /**
     * 将死信交换机与死信队列绑定
     *
     * @param queueDead
     * @param directDeadExchange
     * @return
     */
    @Bean
    public Binding queueDeadToDirectDeadExchange(Queue queueDead, DirectExchange directDeadExchange) {
        return BindingBuilder.bind(queueDead).to(directDeadExchange).with("deadKEY");
    }

    /**
     * 将普通交换机与普通队列进行绑定
     *
     * @param queueOrder
     * @param directExchange
     * @return
     */
    @Bean
    public Binding queueOrderToDirectExchange(Queue queueOrder, DirectExchange directExchange) {
        return BindingBuilder.bind(queueOrder).to(directExchange).with("buy.movie");
    }

    //进行交换机与死信通道添加
    @Bean
    public void createExchangeQueue() {
        rabbitAdmin.declareExchange(directExchange());
        rabbitAdmin.declareExchange(directDeadExchange());
        rabbitAdmin.declareQueue(queueOrder());
        rabbitAdmin.declareQueue(queueDead());
    }
}
